Repository navigation
Complete Kernel-managed Visa card checkout in CLI - #283
Merged
Merged
Conversation
rgarcia
approved these changes
Oct 13, 2026
rgarcia
left a comment
Contributor
There was a problem hiding this comment.
approving — the gating and validation look correct against the openapi spec, and the tests cover the important refusals. most of the findings are about agent steering: where guidance says "don't retry" or "stop" without a recovery path, and where the cli, the mcp server (kernel/kernel-mcp-server#238) and openapi disagree. i'd like the dead ends fixed here or in a fast follow, with #238 matched to the same wording.
dead ends (guidance that leaves the agent with no next step)
cmd/vaults_help.go:15(+ mcp #238kernelVerificationGuidance) — "invoke it once" strands the agent if the response is lost. the api re-checks restart availability on every call and commits only if the item is unchanged, and restart is no longer listed once it succeeds. suggest: "if the result is unclear, re-read the item and invoke again only if restart_verification is still listed"cmd/vaults_help.go:15,cmd/vaults.go:290,cmd/vaults_output.go:451— when restart isn't listed: "do not retry, delete, or replace; reconcile with support". delete returns 409 for a kernel card in recovery, so the agent and user have no next step. what should the user do to complete the purchase — a new card item under a new key on the same wallet? if that's safe for this recovery phase, say so with a "one more attempt after user confirmation" limit; if not, say what support does and what state the item ends incmd/vaults_commands.go:237(also:101,cmd/vaults_help.go:133,cmd/vaults_output.go:521, README) — "do not report or retry unknown outcomes, including transport loss". the server finishes after a client disconnect, and confirm_transaction is listed only when no report is in flight, none is recorded, and the item isn't in recovery. a provider rejection releases the claim, so the operation is listed again. suggest: "if the result is unclear, run items get; if confirm_transaction is still listed, the report wasn't recorded — send it once more; otherwise stop." mcp #238 has the same dead end- same lines — "do not report unknown outcomes" gives no next step. confirm_transaction stays listed while the card is ready or expired and unreported, so: tell the user the outcome is unknown, and report it later once they see it (merchant email, order page, statement). also say when to use PENDING/ERROR and when to call an outcome "unknown"; as written, an agent looking at a "processing…" page can't tell, and the cautious choice is to never report
cmd/vaults_output.go:528— kernel wallet guidance always says "share the card_enrollment url". openapi: reconnect_required → the cardholder uses the new card_enrollment action; degraded → "the wallet must be deleted before adding another card". degraded needs its own guidance, e.g. "with user confirmation, delete this wallet and create a new one for one new enrollment". mcp #238 is also silent herecmd/vaults_output.go:558,cmd/vaults_help.go:20— "wait for single_use_card.eligible" has no limit and no exit. reasons arenetwork_token_<status>from the provider, and the README says ineligible can mean "pending or unsupported". say which reasons are terminal and give the path: enroll a different card through a new wallet, after user confirmationcmd/vaults_output.go:502— the kernel card info line prints for every status, including declined, expired and consumed, where "Visa may require spend_approval… submit before expires_at" is misleading. the api allows deleting expired and declined cards, so: expired without submitting → if the user did submit, report first (confirm_transaction is still listed while expired); otherwise, with user confirmation, delete and create one new card item. declined → same, after the user picks a different card or merchantcmd/vaults_commands.go:425,cmd/vaults_help.go:126— "cannot be updated" has three answers. openapiKernelCardVaultItemSpec: "delete and create a new item instead". this PR: "create a new card item for a new purchase" (dropped the old "delete the item and create a new one"). mcp #238: "inspect the existing item", which leaves no next step. suggest all three say: delete (if the api allows it) and create a new item, after user confirmation
cross-surface consistency
cmd/vaults_help.go:15vs mcp #238kernelVerificationGuidance— mcp requires explicit user approval before restart_verification; cli doesn't mention approvalcmd/vaults_help.go:15— mirror the openapi wording: restart doesn't grant spend consent; the cardholder must verify and approve again on the new linkcmd/vaults_commands.go:241,289,README.md:538,564,wallets get --open—--openon cardholder urls (card_enrollment, spend_approval) opens them on the machine running the cli. mcp #238 says "share privately with the cardholder, never open it for them". when an agent runs the cli, that opens the cardholder's capability url in the agent's own browser. pick one rule for both surfacescmd/vaults.go:~340— a confirm_transaction failure goes toutil.CleanedUpSdkErrorwith no next step. mcp #238'sthrowKernelVaultErrorseparates "rejected (4xx): nothing new was authorized; fix inputs before another request" from uncertain failures. the cli should give the same per-error-class guidancecmd/vaults_commands.go:234— openapi and mcp both say the currency "must match the approved purchase currency"; cli help only says "three uppercase letters"cmd/vaults_commands.go:203vs mcp #238 — cli lists kernel fill fields asnumber, expiration (MM/YY or MM/YYYY), cvc, exp_month, exp_year; mcp listsnumber, expiration ("MM/YY"), cvc. align to what the api supportsREADME.md:550— the card spec example uses"currency":"usd"and the confirm example uses"USD". use"USD"in both so a copy-pasting agent doesn't think they differ
questions
cmd/vaults_policy.go:32-40vscmd/vaults_output.go:41— human output filters recovery operations, but-o jsonpasses available_operations through unchanged. intentional? agents mostly read json
nits
cmd/vaults.go:290-293— "do not retry…" followed by "invoke restart_verification once" reads contradictory; consider a separate message for the listed casecmd/vaults.go:292,cmd/vaults_output.go:452—len(actions.Operations) > 0stands in for "restart listed"; an explicit check survives future recovery operationscmd/vaults_confirm_transaction.go:36-44— the length check plus letter loop could be one^[A-Z]{3}$regexp, matching the openapi pattern word for word
follow-up (pre-existing, not this PR)
cmd/vaults_commands.go:218— "transport loss remains an uncertain outcome" for fill has no path. mcp #238 says to inspect the page and item state, then the field write is safe to retry. worth aligning in a separate PR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
summary
number,expirationMM/YYorMM/YYYY,cvc,exp_month,exp_year); optional actualmerchant_category/merchant_category_codeconfirm_transactionthrough--paramsor--spec-file, validating required fields, enums, integer amounts,^[A-Z]{3}$currency, RFC3339 timestamps, and unknown/duplicate properties before any request; reject a currency that differs from the approved purchase or an amount above it; send the exact JSON body without automatic retriesrestart_verificationinrecovery_required; human output,-o json, and execution all hide other operations and stale recovery action URLsRetry-Afterstatus_reason, and event timestamps; never delete or replace the unresolved itemPENDING/ERRORneed explicit merchant evidencereconnect_required/degraded, and boundednetwork_token_*eligibility re-checks*kernel.Errorstatus/code classification without the raw request/responsefield_unavailableon Kernel fill now says billing details go on the merchant page, instead of "collect missing values"--openhelp says cardholder links are for a human on their own machine; agents share them privatelycompatibility
confirm_transactionandrestart_verificationavailability is always gated onavailable_operationsconfirm_transactionorrestart_verificationrequest types. confirmation usesoption.WithRequestBodywith validated JSON andoption.WithMaxRetries(0); replace the raw body with the typed parameter once the SDK is regeneratedvalidation
make testpassed (go vet ./...andgo test ./...)make buildpassedgolangci-lint run --new-from-rev=origin/main: 0 issues. fullmake lintstill masks pre-existing warnings; no unrelated lint cleanup includedfield_unavailable, and--openhelpfollow-up
transport loss remains an uncertain outcome) is left unchanged here and should be aligned with the MCP "inspect the page and item, then retry the field write" wording in a separate PRNote
High Risk
Changes payment credential flows, recovery behavior, and outcome reporting—mistakes could cause duplicate charges, wrong reconciliation, or unsafe handling of card data.
Overview
Adds Kernel-managed vault payments to the CLI:
kernelwallets/cards,vaults wallets get, hosted enrollment, token-eligibility guidance, browser fill for ready Kernel cards (no stored billing; origin locked tomerchant_url), and blocking card PAN/CVC/expiry in--spec.Introduces
confirm_transactionvia--params/--spec-filewith strict local validation and a raw JSON POST (no retries) until the SDK exposes the operation type.Tightens
recovery_required: only an advertised, parameterlessrestart_verification(optional--open) may run; other operations stay blocked with updated errors and human guidance. README and command help document the full Kernel checkout flow (authorize → fill → one-time outcome report).Reviewed by Cursor Bugbot for commit a18d8a8. Bugbot is set up for automated code reviews on this repo. Configure here.